/*
* Flags
*/
-#define CSCHED_FLAG_VCPU_PARKED 0x0001 /* VCPU over capped credits */
+#define CSCHED_FLAG_VCPU_PARKED 0x0001 /* VCPU over capped credits */
+#define CSCHED_FLAG_VCPU_YIELD 0x0002 /* VCPU yielding */
/*
#endif /* CSCHED_STATS */
+/*
+ * Boot parameters
+ */
+int sched_credit_default_yield = 0;
+boolean_param("sched_credit_default_yield", sched_credit_default_yield);
+
/*
* Physical CPU
*/
break;
}
+ /* If the vcpu yielded, try to put it behind one lower-priority
+ * runnable vcpu if we can. The next runq_sort will bring it forward
+ * within 30ms if the queue too long. */
+ if ( svc->flags & CSCHED_FLAG_VCPU_YIELD
+ && __runq_elem(iter)->pri > CSCHED_PRI_IDLE )
+ {
+ iter=iter->next;
+
+ /* Some sanity checks */
+ BUG_ON(iter == runq);
+ }
+
list_add_tail(&svc->runq_elem, iter);
}
__runq_tickle(cpu, svc);
}
+static void
+csched_vcpu_yield(const struct scheduler *ops, struct vcpu *vc)
+{
+ struct csched_vcpu * const sv = CSCHED_VCPU(vc);
+
+ if ( !sched_credit_default_yield )
+ {
+ /* Let the scheduler know that this vcpu is trying to yield */
+ sv->flags |= CSCHED_FLAG_VCPU_YIELD;
+ }
+}
+
static int
csched_dom_cntl(
const struct scheduler *ops,
snext->pri = CSCHED_PRI_TS_BOOST;
}
+ /*
+ * Clear YIELD flag before scheduling out
+ */
+ if ( scurr->flags & CSCHED_FLAG_VCPU_YIELD )
+ scurr->flags &= ~(CSCHED_FLAG_VCPU_YIELD);
+
/*
* SMP Load balance:
*
.sleep = csched_vcpu_sleep,
.wake = csched_vcpu_wake,
+ .yield = csched_vcpu_yield,
.adjust = csched_dom_cntl,